// ========================================================
// Des：
// Creator：DD 
// Time：2021-01-28 11:39:42
// Version：1.0
// ========================================================

using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Text;
using UnityEngine;
using ProtoBuf;

namespace DDCodeBase
{
    public static class ToolKit
    {
        public static int GetRandomInt(int min = 0, int max = 100)
        {
            return new System.Random(GetRandomSeed()).Next(min, max);
        }

        public static float GetRandomFloat(int min = 0, int max = 100)
        {
            return new System.Random(GetRandomSeed()).Next(min, max);
        }

        static int GetRandomSeed()
        {

            byte[] bytes = new byte[4];

            System.Security.Cryptography.RNGCryptoServiceProvider r = new System.Security.Cryptography.RNGCryptoServiceProvider();

            r.GetBytes(bytes);

            return BitConverter.ToInt32(bytes, 0);
        }

        public static string BytesConvertToStr(byte[] bytes)
        {
            String str = null;

            foreach (var B in bytes)
            {
                str = str + Convert.ToString(B, 16) + " ";
            }

            Debug.Log(str);
            return str;
        }

        public static void OutputDataPackage(byte[] bytes)
        {
            Debug.Log(BitConverter.ToString(bytes, 0));
        }

        public static byte[] StrConvertToBytes(string str)
        {
            str = str.Replace("-", "");
            if ((str.Length % 2) != 0)
            {
                str = str.Insert(str.Length - 1, 0.ToString());
            }
            byte[] returnBytes = new byte[str.Length / 2];
            for (int i = 0; i < returnBytes.Length; i++)
            {
                returnBytes[i] = Convert.ToByte(str.Substring(i * 2, 2), 16);
            }
            return returnBytes;
        }

        public static void OutputBytesToFloatData(byte[] bytes, int startIndex)
        {
            float data = BitConverter.ToSingle(bytes, startIndex);

            Debug.Log(data);
        }

        public static string Baodate2Chinese(string strDate)
        {
            char[] strChinese = new char[] {
                         '〇','一','二','三','四','五','六','七','八','九','十'
                     };
            StringBuilder result = new StringBuilder();


            if (!string.IsNullOrEmpty(strDate))
            {
                string[] str = null;
                if (strDate.Contains("-"))
                {
                    str = strDate.Split('-');
                }
                else if (strDate.Contains("/"))
                {
                    str = strDate.Split('/');
                }
                for (int i = 0; i < str[0].Length; i++)
                {
                    result.Append(strChinese[int.Parse(str[0][i].ToString())]);
                }
                result.Append("年");

                int month = int.Parse(str[1]);
                int MN1 = month / 10;
                int MN2 = month % 10;

                if (MN1 > 1)
                {
                    result.Append(strChinese[MN1]);
                }
                if (MN1 > 0)
                {
                    result.Append(strChinese[10]);
                }
                if (MN2 != 0)
                {
                    result.Append(strChinese[MN2]);
                }
                result.Append("月");

                int day = int.Parse(str[2]);
                int DN1 = day / 10;
                int DN2 = day % 10;

                if (DN1 > 1)
                {
                    result.Append(strChinese[DN1]);
                }
                if (DN1 > 0)
                {
                    result.Append(strChinese[10]);
                }
                if (DN2 != 0)
                {
                    result.Append(strChinese[DN2]);
                }
                result.Append("日");
            }
            else
            {
                throw new ArgumentException();
            }

            return result.ToString();
        }

        public static byte[] Compress(byte[] inputBytes)
        {
            using (MemoryStream outStream = new MemoryStream())
            {
                using (GZipStream zipStream = new GZipStream(outStream, CompressionMode.Compress, true))
                {
                    zipStream.Write(inputBytes, 0, inputBytes.Length);
                    return outStream.ToArray();
                }
            }
        }

        public static byte[] Decompress(byte[] inputBytes)
        {
            using (MemoryStream inputStream = new MemoryStream(inputBytes))
            {
                using (MemoryStream outStream = new MemoryStream())
                {
                    using (GZipStream zipStream = new GZipStream(inputStream, CompressionMode.Decompress))
                    {
                        zipStream.CopyTo(outStream);
                        zipStream.Close();
                        return outStream.ToArray();
                    }
                }

            }
        }

        public static Vector3 StringParseVector3(string str)
        {
            str = str.Replace("(", "").Replace(")", "");
            string[] temp = str.Split(',');
            return new Vector3(float.Parse(temp[0]), float.Parse(temp[1]), float.Parse(temp[2]));
        }

        public static List<Vector3> StringParseVector3List(string str)
        {
            List<Vector3> l = new List<Vector3>();
            string[] sa = str.Split('_');

            for (int i = 0; i < sa.Length; i++)
            {
                l.Add(StringParseVector3(sa[i]));
            }

            return l;
        }

        public static Vector2 StringParseVector2(string str)
        {
            Vector2 v;
            str = str.Replace("(", "").Replace(")", "");
            string[] temp = str.Split(',');

            try
            {
                v.x = int.Parse(temp[0]);
                v.y = int.Parse(temp[1]);
            }
            catch (Exception)
            {
                v.x = float.Parse(temp[0]);
                v.y = float.Parse(temp[1]);
            }

            return v;
        }

        public static List<Vector2> StringParseVector2List(string str)
        {
            List<Vector2> l = new List<Vector2>();
            string[] sa = str.Split('_');

            for (int i = 0; i < sa.Length; i++)
            {
                l.Add(StringParseVector2(sa[i]));
            }

            return l;
        }

        public enum ColorType
        {
            Red,
            Green,
            Black,
            Orange,
        }

        private const string RedRichTextHead = "<color=#EA4E2B>";
        private const string GreenRichTextHead = "<color=#51C551>";
        private const string BlackRichTextHead = "<color=#575757>";
        private const string OrangeRichTextHead = "<color=#FF7000>";
        private const string RichTextTail = "</color>";

        public static string GetColorRichTextString(string str, ColorType color = ColorType.Black)
        {
            StringBuilder stringBuilder = new StringBuilder(str);

            switch (color)
            {
                case ColorType.Red:
                    stringBuilder.Insert(0, RedRichTextHead);
                    break;
                case ColorType.Green:
                    stringBuilder.Insert(0, GreenRichTextHead);
                    break;
                case ColorType.Black:
                    stringBuilder.Insert(0, BlackRichTextHead);
                    break;
                case ColorType.Orange:
                    stringBuilder.Insert(0, OrangeRichTextHead);
                    break;
                default:
                    stringBuilder.Insert(0, BlackRichTextHead);
                    break;
            }

            return stringBuilder.Append(RichTextTail).ToString();
        }

        #region 使用ProtoBuf序列化和反序列化

        public interface ByteArrayAble<T> where T : ByteArrayAble<T>
        {
            T FromBytes(byte[] data, int offset, int size);
            byte[] ToBytes();
        }

        public abstract class AbstractBAA<T> : ByteArrayAble<T> where T : ByteArrayAble<T>
        {
            public T FromBytes(byte[] data, int offset, int size)
            {
                return DirectProtoBufTools.Deserialize<T>(data, offset, size);
            }
            public byte[] ToBytes()
            {
                return DirectProtoBufTools.Serialize(this);
            }
        }

        public static class DirectProtoBufTools
        {
            public static byte[] Serialize(object obj)
            {
                using (var memory = new MemoryStream())
                {
                    ProtoBuf.Serializer.Serialize(memory, obj);
                    return memory.ToArray();
                }
            }

            public static T Deserialize<T>(byte[] data)
            {
                using (var memory = new MemoryStream(data))
                    return ProtoBuf.Serializer.Deserialize<T>(memory);
            }

            public static T Deserialize<T>(byte[] data, int offset, int size)
            {
                using (var memory = new MemoryStream(data, offset, size))
                    return ProtoBuf.Serializer.Deserialize<T>(memory);
            }

#if HSFRAMEWORK_NET_ABOVE_4_5
		        public static T Deserialize<T>(SmartBuffer sb)
		        {
		        return Deserialize<T>(sb.Data, sb.Offset, sb.Size);
		        }
#endif
        }

        #endregion

        public static void DebugLogList<T>(List<T> ls)
        {
            foreach (var value in ls)
            {
                Debug.Log(value);
            }
        }
    }
}
